<template>
  <div>
    <div ref="codeEditorRef" style="height: 550px" />
  </div>
</template>

<script setup lang="ts" name="CodeEditor">
import * as monaco from "monaco-editor"
import EditorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker"
import { toRaw } from "vue"
const props = defineProps({
  modelValue: {
    type: String,
    default: ""
  },
  language: {
    type: String,
    required: true,
    default: "sql"
  },
  theme: {
    type: String,
    required: true,
    default: "vs"
  },
  readOnly: {
    type: Boolean,
    required: true,
    default: false
  },
  fontSize: {
    type: Number,
    default: 15
  }
})

const codeEditorRef = ref(null)
const initEditor = ref()
const emits = defineEmits(["handleModelValue"])

defineExpose({ cleanCodeValue })

self.MonacoEnvironment = {
  getWorker(moduleId: String, label: String) {
    return new EditorWorker()
  }
}

function cleanCodeValue() {
  toRaw(initEditor.value).setValue("")
}

onMounted(async () => {
  // 初始化代码编辑器
  if (codeEditorRef.value) {
    initEditor.value = monaco.editor.create(codeEditorRef.value, {
      value: props.modelValue,
      language: props.language,
      theme: props.theme,
      automaticLayout: true,
      readOnly: props.readOnly,
      fontSize: props.fontSize
    })
    initEditor.value.onDidChangeModelContent(() => {
      emits("handleModelValue", toRaw(initEditor.value).getValue())
    })
  }
})

watch(
  () => props.modelValue,
  () => {
    if (codeEditorRef.value && initEditor.value) {
      toRaw(initEditor.value).setValue(props.modelValue)
    }
  }
)

onUnmounted(() => {
  if (initEditor.value) {
    toRaw(initEditor.value).dispose()
  }
})
</script>

<style></style>
